package com.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blog.constants.SystemConstants;
import com.blog.domain.ResponseResult;
import com.blog.domain.entity.Menu;
import com.blog.domain.vo.MenuVo;
import com.blog.enums.AppHttpCodeEnum;
import com.blog.exception.SystemException;
import com.blog.mapper.MenuMapper;
import com.blog.service.MenuService;
import com.blog.utils.BeanCopyUtils;
import com.blog.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2024-09-11 14:20:27
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

	@Autowired
	private MenuMapper menuMapper;
	@Override
	public List<String> selectPermByUserId(Long userid) {

		//如果是管理员，返回所有的权限. 1为管理员
     if (SecurityUtils.isAdmin()){
      LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
      //封装条件，菜单类型为C或者F（菜单、按钮）
      wrapper.in(Menu::getMenuType,SystemConstants.MENU,SystemConstants.BUTTON);
	  //条件，状态为正常未删除，0为正常
	  wrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);

	     List<Menu> menus = list(wrapper);
			//拿到权限，字符串类型的
	     List<String> perms = menus.stream()
			     .map(Menu::getPerms).collect(Collectors.toList());

		 return perms;
     }

     //不是管理，返回查询到的权限
		return menuMapper.selectPermByUserId(userid);
	}



	@Override
	public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
		List<Menu> menus = null;
		//是管理员。返回所有符合条件的menu
		if (SecurityUtils.isAdmin()){
			menus = menuMapper.selectAllRouterMenu();
		}else {
			//不是，获取用户具有的menu
			menus = menuMapper.selectRouterMenuTreeByUserId(userId);
		}

		//构建树
		//先找出第一层菜单，然后去找他们的子菜单设置道children中
		List<Menu> menuTree = buildMenuTree(menus,0L);

		return menuTree;
	}
	/**菜单查询
	 *
	 * @param status 状态
	 * @param menuName  菜单名
	 * @return
	 */
	@Override
	public List<Menu> menuList(String status, String menuName) {
		LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();

		wrapper.eq(StringUtils.hasText(status),Menu::getStatus,status);
		wrapper.like(StringUtils.hasText(menuName),Menu::getMenuName,menuName);

		wrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);

		List<Menu> menuList = list(wrapper);

		return menuList;


	}

	/**新增菜单
	 *
	 * @param menu
	 * @return
	 */
	@Override
	public ResponseResult addMenu(Menu menu) {
			save(menu);
			return ResponseResult.okResult();

	}

	/**菜单详情回显
	 *
	 * @param id
	 * @return
	 */
	@Override
	public ResponseResult getMenuDetailById(Long id) {
		Menu menu = getById(id);
		MenuVo menuVo = BeanCopyUtils.copyBean(menu, MenuVo.class);
		return ResponseResult.okResult(menuVo);
	}

	/**更新菜单
	 *
	 * @param menu
	 * @return
	 */
	@Override
	public ResponseResult updateMenu(Menu menu) {
		//判断当前更新内容中有没有把自己设置为父菜单
		if (menu.getParentId().equals(menu.getId())){
			throw new SystemException(AppHttpCodeEnum.PARENTID_ERROR);
		}
		updateById(menu);
		return ResponseResult.okResult();
	}

	/**删除菜单
	 *
	 * @param menuId
	 * @return
	 */
	@Override
	public ResponseResult deleteMenu(Long menuId) {

		Menu menu = getById(menuId);

		Long userId = SecurityUtils.getUserId();
		List<Menu> menus = null;
		//是管理员。返回所有符合条件的menu
		if (SecurityUtils.isAdmin()){
			menus = menuMapper.selectAllMenu();
		}else {
			//不是，获取用户具有的menu
			menus = menuMapper.selectRouterMenuTreeByUserId(userId);
		}

		List<Menu> menuList = buildMenuTree(menus, menu.getId());
		//如果有子菜单存在，不能删除
		//子菜单不为空，抛出异常
		if (!CollectionUtils.isEmpty(menuList)){
			throw new SystemException(AppHttpCodeEnum.CHILDREN_ERROR);
		}
		//为空，正常删除
		removeById(menuId);
		return ResponseResult.okResult();
	}

	/**
	 * 构建树
	 *
	 * @param menus
	 * @param
	 * @return
	 */

	private List<Menu> buildMenuTree(List<Menu> menus, Long parentId) {
		List<Menu> menuTree = menus.stream()
				.filter(menu -> menu.getParentId().equals(parentId))
				.map(menu -> menu.setChildren(getChildren(menu, menus)))
				.collect(Collectors.toList());
		return menuTree;
	}

	/**
	 * 获取存入参数的子menu
	 *
	 * @param menu
	 * @param menus
	 * @return
	 */
	private List<Menu> getChildren(Menu menu, List<Menu> menus) {
		List<Menu> childrenList = menus.stream()
				.filter(m -> m.getParentId().equals(menu.getId()))
				.collect(Collectors.toList());
		return childrenList;
	}
}
